package cn.schoolwow.quickdao.module.database.dql.response.flow.update;

import cn.schoolwow.quickdao.domain.QuickDAOConfig;
import cn.schoolwow.quickdao.domain.provider.DatabaseProvider;
import cn.schoolwow.quickdao.module.database.dql.condition.flow.common.SetJoinTableOnAndStatementFlow;
import cn.schoolwow.quickdao.module.database.dql.condition.flow.common.SetSingleJoinTableStatementFlow;
import cn.schoolwow.quickdao.module.database.dql.parent.domain.QueryContext;
import cn.schoolwow.quickdao.module.database.dql.subCondition.domain.SubQueryOption;
import cn.schoolwow.quickflow.domain.FlowContext;
import cn.schoolwow.quickflow.flow.BusinessFlow;

public class PostgresUpdateStatementFlow implements BusinessFlow {
    @Override
    public void executeBusinessFlow(FlowContext flowContext) throws Exception {
        QuickDAOConfig quickDAOConfig = flowContext.checkInstanceData(QuickDAOConfig.class);
        QueryContext queryContext = (QueryContext) flowContext.checkData("queryContext");
        DatabaseProvider databaseProvider = quickDAOConfig.databaseContext.databaseProvider;

        StringBuilder sqlBuilder = new StringBuilder();
        sqlBuilder.append("update " + databaseProvider.escape(queryContext.queryOption.queryTableOption.entity.tableName) + " " + queryContext.queryOption.queryTableOption.tableAliasName + " ");
        sqlBuilder.append(queryContext.set);

        if(queryContext.queryOption.subQueryOptionList.size()>=1){
            SubQueryOption subQueryOption = queryContext.queryOption.subQueryOptionList.get(0);
            sqlBuilder.append(" from " + databaseProvider.escape(subQueryOption.subQueryTableOption.entity.tableName));
            sqlBuilder.append(" " + subQueryOption.subQueryTableOption.tableAliasName);
        }
        if(queryContext.queryOption.subQueryOptionList.size()>1){
            for(int i=1;i<queryContext.queryOption.subQueryOptionList.size();i++){
                SubQueryOption subQueryOption = queryContext.queryOption.subQueryOptionList.get(i);
                flowContext.startFlow(new SetSingleJoinTableStatementFlow())
                        .putCurrentCompositeFlowData("subQueryOption", subQueryOption)
                        .putCurrentCompositeFlowData("sqlBuilder", sqlBuilder)
                        .execute();
            }
        }
        //添加where语句的关联语句
        if(queryContext.queryOption.subQueryOptionList.size()>=1){
            SubQueryOption subQueryOption = queryContext.queryOption.subQueryOptionList.get(0);

            StringBuilder whereBuilder = new StringBuilder();
            if (null != subQueryOption.subQueryJoinTableOption.primaryField && null != subQueryOption.subQueryJoinTableOption.joinTableField) {
                if (subQueryOption.subQueryJoinTableOption.parentSubQueryOption == null) {
                    //子表关联主表
                    whereBuilder.append(subQueryOption.subQueryJoinTableOption.queryOption.queryTableOption.tableAliasName + "." + quickDAOConfig.databaseContext.databaseProvider.escape(subQueryOption.subQueryJoinTableOption.primaryField));
                } else {
                    //子表关联子表
                    whereBuilder.append(subQueryOption.subQueryJoinTableOption.parentSubQueryOption.subQueryTableOption.tableAliasName + "." + quickDAOConfig.databaseContext.databaseProvider.escape(subQueryOption.subQueryJoinTableOption.primaryField));
                }
                whereBuilder.append(" = " + subQueryOption.subQueryTableOption.tableAliasName + "." + quickDAOConfig.databaseContext.databaseProvider.escape(subQueryOption.subQueryJoinTableOption.joinTableField) + " ");

                flowContext.startFlow(new SetJoinTableOnAndStatementFlow())
                        .putCurrentCompositeFlowData("sqlBuilder", sqlBuilder)
                        .putCurrentCompositeFlowData("subQueryOption", subQueryOption)
                        .execute();
            }
            if(queryContext.where.isEmpty()){
                sqlBuilder.append(" where "+whereBuilder.toString()+" ");
            }else{
                sqlBuilder.append(queryContext.where.replace("where ", " where "+whereBuilder+" and "));
            }
        }else{
            sqlBuilder.append(queryContext.where);
        }
        flowContext.putTemporaryData("sql", sqlBuilder.toString());
    }

    @Override
    public String name() {
        return "Postgres数据库更新语句";
    }
}
